#!/usr/bin/env python
# encoding: utf-8


"""
@file: triangle_question_converts.py
@time: 2017/2/16 下午2:43
"""
from mathsolver.functions.base import *
from sympy import sin, cos, simplify, expand_trig, tan, cot, acos
from mathsolver.functions.sanjiao import sanjiao_utils as sanjiao


# 三角形已知问题转换


def _angle_convert(angle_name):
    """
    求角的转换 求角A，B，C
    :param angle_name:
    :return:
    """
    angle = sympify(angle_name)
    if not (len(str(angle)) == 1 and str(list(angle.free_symbols)[0]) in ['A', 'B', 'C']):
        raise Exception('Type Match Error')
    return {cos(angle): acos}
    # return {sin(angle): asin, cos(angle): acos}


def _trig_f_convert(trig_f):
    """
    求角三角函数值的转变. 如求sin(A), cos(A)
    :param trig_f:
    :return:
    """
    trig_f = sympify(trig_f)
    two_angle_subs = (('A+B', 'pi - C'), ('A+C', 'pi - B'), ('B+C', 'pi - A'))
    trig_f = expand_trig(trig_f.subs(two_angle_subs))
    symbs = list(trig_f.free_symbols)
    if len(symbs) != 1:
        raise Exception('Type Match Error')
    symb = symbs[0]
    angle_subs = (('sin(A)', ''), ('cos(A)', ''), ('tan(A)', ''), ('cot(A)', ''),
                  ('sin(B)', ''), ('cos(B)', ''), ('tan(B)', ''), ('cot(B)', ''),
                  ('sin(C)', ''), ('cos(C)', ''), ('tan(C)', ''), ('cot(C)', ''))
    sub_f = trig_f.subs(angle_subs)
    sub_f_symbs = list(sub_f.free_symbols)
    if sub_f.is_real or (len(sub_f_symbs) == 1 and sub_f_symbs[0] == sympify('')):
        trig_type = None
        try:
            trig_type = sanjiao.trig_type(trig_f)
        except Exception:
            pass
        if trig_type in [sin, cos, cot, tan]:
            return {trig_type(symb): lambda v: trig_f.subs(trig_type(symb), v)}
        else:
            def _poly_subs(_cos_v):
                sin_v = sqrt(1 - _cos_v ** 2)
                tan_v = sin_v / _cos_v
                cot_v = _cos_v / sin_v
                _f = trig_f
                trig_value_subs = ((sin(symb), sin_v), (cos(symb), _cos_v), (tan(symb), tan_v), (cot(symb), cot_v))
                return simplify(_f.subs(trig_value_subs))

            return {cos(symb): _poly_subs}
    else:
        raise Exception('Type Match Error')


# 求边的值, 边a, b, c
def _line_convet(line_name):
    line_subs = (('baseLine(AB)', 'c'), ('baseLine(AC)', 'b'), ('baseLine(BC)', 'a'))
    symb_line_subs = (('AB', 'c'), ('AC', 'b'), ('BC', 'a'))
    line_f = sympify(line_name).subs(line_subs).subs(symb_line_subs)
    if str(line_f) not in ['a', 'b', 'c']:
        raise Exception('Type Match Error')
    return {sympify(line_f): lambda _: _}


def _subs_convert(trig_f):
    # 直接用subs()转换
    trig_f = sympify(trig_f)
    sub_key = list(trig_f.as_coefficients_dict().items())[0][0]
    return {sub_key: lambda sub_value: trig_f.subs(sub_key, sub_value)}


_question_converts = [_angle_convert, _trig_f_convert, _line_convet, _subs_convert]


def question_convets(q):
    question_eq_converts = {}
    for q_c in _question_converts:
        try:
            eq_maps = q_c(q)
            for k, v in eq_maps.items():
                question_eq_converts[k] = v
        except Exception:
            pass
    return question_eq_converts
